package com.example.rtmppusher;

import android.Manifest;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.example.rtmppusher.push.AudioRecordHandler;
import com.example.rtmppusher.push.CameraPreviewHandler;
import com.example.rtmppusher.push.EventListener;
import com.example.rtmppusher.push.RtmpPusher;
import com.example.rtmppusher.util.CameraUtils;
import com.example.rtmppusher.util.Utils;

public class PlayActivity extends AppCompatActivity {

    AspectRatioSurfaceView surfaceView;
    Button switchButton;
    Button startButton;
    Button stopButton;

    AudioRecordHandler audioRecordHandler;
    CameraPreviewHandler cameraPreviewHandler;
    RtmpPusher pusher = new RtmpPusher();

    boolean surfaceFirstCreated = true;

    //    final String url = "rtmp://192.168.33.237:18005/live/10086";
    final String url = "rtmp://139.159.226.207:1935/hls/test";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED ||
                ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this, "申请权限", Toast.LENGTH_SHORT).show();
            // 申请 相机 麦克风权限
            ActivityCompat.requestPermissions(this, new String[]{
                    Manifest.permission.INTERNET,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.CAMERA}, 100);
        }

        switchButton = findViewById(R.id.switchButton);
        startButton = findViewById(R.id.startButton);
        stopButton = findViewById(R.id.stopButton);
        surfaceView = findViewById(R.id.surfaceView);

        //创建推流器
        pusher.setEventListener(new RtmpPusher.EventListener() {

            @Override
            public void beforePrepare() {
                Utils.hide(startButton);
                Utils.hide(stopButton);
            }

            @Override
            public void onPrepared() {
                Utils.show(startButton);
                Utils.show(stopButton);
                Log.e("PlayActivity", "prepared...");
            }

            @Override
            public void beforeRelease() {
                Utils.hide(startButton);
                Utils.hide(stopButton);
            }

            @Override
            public void onReleased() {
                //如果release后面还有再prepare的操作，要等prepare成功后再显示
                //虽然beforePrepare时会隐藏控件，但这个是交给主线程Handler去做的，不会立刻生效
                //在这期间用户可能再次乱操作，引发流程混乱
                Utils.sleep(200);
                if (pusher.taskQueue.actions.isEmpty()) {
                    Utils.show(startButton);
                    Utils.show(stopButton);
                }
            }

            @Override
            public void onError(int code, String message) {
                Log.e("RtmpPusher onError", message);
            }
        });
        pusher.initialize();

        //创建事件监听器
        EventListener listener = new EventListener() {
            @Override
            public void onAudioFrame(byte[] bytes) {
                //向服务器推音频帧
                pusher.pushAudioFrame(bytes);
            }

            @Override
            public void onVideoFrame(byte[] bytes) {
                //向服务器推视频帧
                byte[] reversedBytes = new byte[bytes.length];
                byte[] rotatedBytes = new byte[bytes.length];
                Camera.Size previewSize = cameraPreviewHandler.getPreviewSize();
                int face = cameraPreviewHandler.getFace();
                int cameraOrientation = cameraPreviewHandler.getCameraOrientation();
                int displayRotation = cameraPreviewHandler.getDisplayRotation();
                int frameRotation = CameraUtils.getFrameRotation(face, cameraOrientation, displayRotation);
                CameraUtils.rotateNV21(face, bytes, reversedBytes, rotatedBytes, previewSize.width, previewSize.height, frameRotation);
                pusher.pushVideoFrame(rotatedBytes);
            }

            @Override
            public void onVideoParamChange(int width, int height) {
                //调整视频推流参数
                int displayRotation = cameraPreviewHandler.getDisplayRotation();
                if (displayRotation == 0 || displayRotation == 180)
                    pusher.setVideoEncodeInfo(height, width, 25, 1000_000);
//                    pusher.setVideoEncodeInfo(height, width, 25, 2000_000);
                else
                    pusher.setVideoEncodeInfo(width, height, 25, 1000_000);
//                    pusher.setVideoEncodeInfo(width, height, 25, 2000_000);
            }

            @Override
            public void onCameraSwitch(int newFace) {
                cameraPreviewHandler.stopPreview();
                cameraPreviewHandler.startPreview();
                cameraPreviewHandler.setPreviewDisplay(surfaceView.getHolder());
            }
        };

        //设置音频参数
        pusher.setAudioEncodeInfo(44100, 2);

        //创建录音器
        int inputSameples = pusher.getInputSamples();
        audioRecordHandler = new AudioRecordHandler(listener);
        audioRecordHandler.setAudioEncodeInfo(44100, 2, inputSameples);
        audioRecordHandler.start();

        //创建摄像头预览器
        cameraPreviewHandler = new CameraPreviewHandler(this, listener);

        //设置SurfaceView生命周期回调
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {

            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                //由于Surface首次创建，会同时出发surfaceCreated和surfaceChanged
                //因此我们执行其中一个回调即可，不需要重复执行
                if (surfaceFirstCreated) {
                    surfaceFirstCreated = false;
                    return;
                }
                //开始预览
                cameraPreviewHandler.startPreview();
                //设置用于预览的SurfaceHolder
                cameraPreviewHandler.setPreviewDisplay(holder);
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                //停止旧的预览
                cameraPreviewHandler.stopPreview();
                //开始新的预览
                cameraPreviewHandler.startPreview();
                //设置用于预览的SurfaceHolder
                cameraPreviewHandler.setPreviewDisplay(holder);
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                //停止预览
                cameraPreviewHandler.stopPreview();
                surfaceFirstCreated = true;
            }
        });

        //切换摄像头
        switchButton.setOnClickListener(v -> {
            cameraPreviewHandler.switchCamera();
        });

        //开始推流
        startButton.setOnClickListener(v -> {
            pusher.release();
            pusher.prepare(url);
            startButton.setEnabled(false);
            stopButton.setEnabled(true);
            Toast.makeText(PlayActivity.this, "开始直播", Toast.LENGTH_SHORT).show();
        });

        //停止推流
        stopButton.setOnClickListener(v -> {
            pusher.release();
            startButton.setEnabled(true);
            stopButton.setEnabled(false);
            Toast.makeText(PlayActivity.this, "停止直播", Toast.LENGTH_SHORT).show();
        });
    }

    @Override
    protected void onResume() {
        CameraUtils.setTranslucentMode(this);
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        audioRecordHandler.stop();
        cameraPreviewHandler.stopPreview();
        pusher.release();
        super.onDestroy();
    }

    //当屏幕快速旋转180度时，Surface的大小不变，不会触发SurfaceView.onSurfaceChange
    //所以就不会触发CameraPreviewHandler.setPreviewOrientation方法，来重新更新预览方向
    //所以必须在Activity.onConfigurationChanged中强制调用一次，保证万无一失
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        cameraPreviewHandler.setPreviewOrientation();
    }
}
